using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using UniversalAdmin.Application.Dto;
using UniversalAdmin.Application.Commands;
using UniversalAdmin.Domain.Entities.App;
using UniversalAdmin.Domain.Repositories;
using System.Linq;
using UniversalAdmin.Shared.Enums;
using UniversalAdmin.Infrastructure.Data.Contexts;

namespace UniversalAdmin.Application.Services
{
    public class AppPermissionService : IAppPermissionService
    {
        private readonly IRepository<AppPermission> _permissionRepository;
        private readonly AdminDbContext _db;
        public AppPermissionService(IRepository<AppPermission> permissionRepository, AdminDbContext db)
        {
            _permissionRepository = permissionRepository;
            _db = db;
        }

        public async Task<ApiResult<PagedResult<PermissionDto>>> GetPagedAsync(PagedQuery query)
        {
            var q = _db.AppPermissions.Where(p => !p.IsDelete);
            if (!string.IsNullOrWhiteSpace(query.Search))
                q = q.Where(p => p.PermissionName.Contains(query.Search) || (p.PermissionCode ?? "").Contains(query.Search) || (p.Name ?? "").Contains(query.Search));
            var total = await Task.FromResult(q.Count());
            var items = q.OrderByDescending(p => p.CreatedAt)
                .ThenBy(p => p.Id)
                .Skip((query.Page - 1) * query.Size)
                .Take(query.Size)
                .Select(p => new PermissionDto
                {
                    Id = p.Id,
                    Name = p.PermissionName,
                    Code = p.PermissionCode,
                    Description = p.Name,
                    IsActive = p.IsActive,
                })
                .ToList();
            return ApiResult<PagedResult<PermissionDto>>.Success((int)ApiStatusCode.SUCCESS, "操作成功", new PagedResult<PermissionDto>(items, total, query.Page, query.Size));
        }

        public async Task<ApiResult<IEnumerable<PermissionDto>>> GetAllAsync(string? search = null)
        {
            var q = _db.AppPermissions.Where(p => !p.IsDelete);
            if (!string.IsNullOrWhiteSpace(search))
                q = q.Where(p => p.PermissionName.Contains(search) || (p.PermissionCode ?? "").Contains(search) || (p.Name ?? "").Contains(search));
            var items = q.OrderByDescending(p => p.CreatedAt)
                .ThenBy(p => p.Id)
                .Select(p => new PermissionDto
                {
                    Id = p.Id,
                    Name = p.PermissionName,
                    Code = p.PermissionCode,
                    Description = p.Name,
                    IsActive = p.IsActive,
                })
                .ToList();
            return ApiResult<IEnumerable<PermissionDto>>.Success((int)ApiStatusCode.SUCCESS, "操作成功", items.AsEnumerable());
        }

        public async Task<ApiResult<PermissionDto>> GetByIdAsync(Guid id)
        {
            var permission = await _permissionRepository.GetByIdAsync(id);
            if (permission == null) return ApiResult<PermissionDto>.Failed("权限不存在", (int)ApiStatusCode.NOT_FOUND);
            return ApiResult<PermissionDto>.Success((int)ApiStatusCode.SUCCESS, "操作成功", new PermissionDto { Id = permission.Id, Code = permission.PermissionCode, Name = permission.PermissionName, Description = permission.Name, IsActive = permission.IsActive });
        }

        public async Task<ApiResult<PermissionDto>> CreateAsync(CreatePermissionDto dto)
        {
            if (_permissionRepository.Table.Any(p => p.PermissionCode == dto.Code))
                return ApiResult<PermissionDto>.Failed("权限编码已存在", (int)ApiStatusCode.CONFLICT);
            var permission = new AppPermission
            {
                Id = Guid.NewGuid(),
                PermissionCode = dto.Code,
                PermissionName = dto.Name,
                Name = dto.Description
            };
            await _permissionRepository.CreatedAsync(permission);
            return ApiResult<PermissionDto>.Success((int)ApiStatusCode.SUCCESS, "创建成功", new PermissionDto { Id = permission.Id, Code = permission.PermissionCode, Name = permission.PermissionName, Description = permission.Name, IsActive = permission.IsActive });
        }

        public async Task<ApiResult<PermissionDto>> UpdateAsync(Guid id, UpdatePermissionDto dto)
        {
            var permission = await _permissionRepository.GetByIdAsync(id);
            if (permission == null) return ApiResult<PermissionDto>.Failed("权限不存在", (int)ApiStatusCode.NOT_FOUND);
            if (_permissionRepository.Table.Any(p => p.PermissionCode == dto.Code && p.Id != id))
                return ApiResult<PermissionDto>.Failed("权限编码已存在", (int)ApiStatusCode.CONFLICT);
            permission.PermissionCode = dto.Code;
            permission.PermissionName = dto.Name;
            permission.Name = dto.Description;
            await _permissionRepository.UpdateAsync(permission);
            return ApiResult<PermissionDto>.Success((int)ApiStatusCode.SUCCESS, "修改成功", new PermissionDto { Id = permission.Id, Code = permission.PermissionCode, Name = permission.PermissionName, Description = permission.Name, IsActive = permission.IsActive });
        }

        public async Task<ApiResult> DeleteAsync(Guid id)
        {
            var permission = await _permissionRepository.GetByIdAsync(id);
            if (permission == null) return ApiResult.Failed((int)ApiStatusCode.NOT_FOUND, "权限不存在");

            // 检查是否已被软删除
            if (permission.IsDelete)
                return ApiResult.Failed((int)ApiStatusCode.CONFLICT, "权限已被删除，不能重复删除");

            // 检查是否被角色引用
            bool isReferenced = _db.AppRoles.Any(r => r.Permissions.Any(p => p.Id == id));
            if (isReferenced)
                return ApiResult.Failed((int)ApiStatusCode.CONFLICT, "该权限已分配给角色，无法删除");

            permission.IsDelete = true;
            await _permissionRepository.UpdateAsync(permission);
            return ApiResult.Success((int)ApiStatusCode.SUCCESS, "删除成功");
        }

        public async Task<ApiResult> EnableAsync(Guid id)
        {
            var permission = await _permissionRepository.GetByIdAsync(id);
            if (permission == null)
                return ApiResult.Failed((int)ApiStatusCode.NOT_FOUND, "权限不存在");
            if (permission.IsDelete)
                return ApiResult.Failed((int)ApiStatusCode.CONFLICT, "权限已被删除，无法启用");
            if (permission.IsActive)
                return ApiResult.Failed((int)ApiStatusCode.CONFLICT, "权限已是启用状态");
            permission.IsActive = true;
            await _permissionRepository.UpdateAsync(permission);
            return ApiResult.Success((int)ApiStatusCode.SUCCESS, "启用成功");
        }

        public async Task<ApiResult> DisableAsync(Guid id)
        {
            var permission = await _permissionRepository.GetByIdAsync(id);
            if (permission == null)
                return ApiResult.Failed((int)ApiStatusCode.NOT_FOUND, "权限不存在");
            if (permission.IsDelete)
                return ApiResult.Failed((int)ApiStatusCode.CONFLICT, "权限已被删除，无法禁用");
            if (!permission.IsActive)
                return ApiResult.Failed((int)ApiStatusCode.CONFLICT, "权限已是禁用状态");
            permission.IsActive = false;
            await _permissionRepository.UpdateAsync(permission);
            return ApiResult.Success((int)ApiStatusCode.SUCCESS, "禁用成功");
        }
    }
} 